/**************************************************************** * fbps.c: FBM Release 1.2 02-Jun-93 Michael Mauldin * * Copyright (C) 1989-1993 by Michael Mauldin. Permission is granted * to use this file in whole or in part for any purpose, educational, * recreational or commercial, provided that this copyright notice * is retained unchanged. This software is available to all free of * charge by anonymous FTP and in the UUNET archives. * * fbps: Convert a grayscale image to a PostScript file * * USAGE * % fbps < image > postscript * * EDITLOG * LastEditDate = Mon Jun 25 00:04:03 1990 - Michael Mauldin * LastFileName = /usr2/mlm/src/misc/fbm/fbps.c * * HISTORY * 02-Jun-93 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon * Add ability to handle mapped/unmapped 1,4,8 bit grayscale and color. * * 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon * Package for Release 1.0 * * 26-Aug-89 Paul Milazzo (milazzo) at BBN * Beta release (version 0.96) * Added rotation, big paper option * * 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University * Beta release (version 0.94) mlm@cs.cmu.edu * * 25-Apr-89 Paul Milazzo (milazzo) at BBN * Added color postscript support * * 27-Aug-88 Michael Mauldin (mlm) at Carnegie-Mellon University * Created. *****************************************************************/ # include # include # include "fbm.h" # define PAPERWIDTH 8.5 /* inches */ # define BIGPAPERWIDTH 11 /* inches */ # define PAPERHEIGHT 11 /* inches */ # define BIGPAPERHEIGHT 14 /* inches */ char *ps_chars(); # define USAGE \ "Usage: fbps [-t -c<credits> -b<banner> -d<dpi> [-pP] [ -rsL ] [ -w<width> ] < foo.fbm > foo.PS" #ifndef lint static char *fbmid = "$FBM fbps.c <1.0> 25-Jun-90 (C) 1989,1990 by Michael Mauldin, source \ code available free from MLM@CS.CMU.EDU and from UUNET archives$"; #endif int resolution = 300; /* dpi */ main (argc, argv) char *argv[]; { register int i, j; int rows, cols, rowlen; double paperwidth, paperheight; double maxwidth, maxheight; double width = -1, height, llx, lly, top, bottom; int bytcnt=0, bigpaper=0, dobanner=1, dotitle=1, docredits=1, dosize=1; int rotate=0, scribe=0, compressed=0; char buf[BUFSIZ]; char *banner=NULL, *title=NULL, *credits=NULL, *creator=NULL; long clock = time ((long *) NULL); char *ctime (); FBM image; int iscolor, bits, padlen; /* Clear the memory pointer so alloc_fbm won't be confused */ image.cm = image.bm = (unsigned char *) NULL; /* Get the options */ while (--argc > 0 && (*++argv)[0] == '-') { while (*++(*argv)) { switch (**argv) { case 'b': banner = *argv+1; dobanner = 1; SKIPARG; break; case 'B': dobanner = 0; break; case 't': title = *argv+1; dotitle = 1; SKIPARG; break; case 'T': dotitle = 0; break; case 'c': credits = *argv+1; docredits = 1; SKIPARG; break; case 'C': docredits = 0; break; case 'p': dosize = 1; break; case 'P': dosize = 0; break; case 'r': rotate++; break; case 'd': resolution = atoi (*argv+1); SKIPARG; break; case 'L': bigpaper++; break; case 's': scribe++; break; case 'w': width = atof (*argv+1); SKIPARG; break; default: fprintf (stderr, "%s\n", USAGE); exit (1); } } } if (!read_bitmap (&image, (char *) NULL)) { exit (1); } /* Get title */ if (!title && image.hdr.title && image.hdr.title[0]) { title = image.hdr.title; } /* Get credits */ if (!credits && image.hdr.credits && image.hdr.credits[0]) { credits = image.hdr.credits; } /* Get width and height */ rows = image.hdr.rows; cols = image.hdr.cols; rowlen = image.hdr.rowlen; paperwidth = bigpaper ? BIGPAPERWIDTH : PAPERWIDTH; paperheight = bigpaper ? BIGPAPERHEIGHT : PAPERHEIGHT; maxwidth = (rotate ? paperheight : paperwidth) - 1.49; maxheight = (rotate ? paperwidth : paperheight) - 1.49; analyze_image (&image, &iscolor, &bits, &padlen); /*==== Choose X and Y size, if width not specified ====*/ if (bits == 1) { int scalex, scaley, rscale; double rwidth, rheight; scalex = (maxwidth * resolution) / cols; scaley = (maxheight * resolution) / rows; rscale = (scalex < scaley) ? scalex : scaley; if (rscale < 1) { fprintf (stderr, "Error: image too large [%d,%d] to fit at %d dpi resolution\n", cols, rows, resolution); exit (1); } width = (double) cols * rscale / (double) resolution; height = (double) rows * rscale / (double) resolution; } else { if (width < 0.0 || width > maxwidth) { width = maxwidth; } height = width * image.hdr.aspect * (double) rows / cols; if (height > maxheight) { width = width * maxheight / height; height = maxheight; } } /* Pick lower left corner */ if (scribe) { llx = lly = 0.0; } else { llx = (paperwidth - (rotate ? height : width)) / 2.0; lly = rotate ? width + ((paperheight - width) / 2.0) : (paperheight - height) / 2.0; } fprintf (stderr, "FBM to PS \"%s\" width %1.3lf inches, height %1.3lf inches\n", title ? title : "(untitled)", width, height); /* Write out PostScript Header */ if (scribe) { printf ("%%! Scribe @graphic style PostScript\n"); if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); } if (banner) { printf ("%%%%Banner: %s\n", ps_chars (banner)); } if (credits) { printf ("%%%%Credits: %s\n", ps_chars (credits)); } if (creator) { printf ("%%%%Creator: %s\n", ps_chars (creator)); } printf ("%%%%CreationDate: %s", ctime (&clock)); printf ("/inch { 72 mul } def\n"); printf ("/picstr %d string def\n\n", BYTESPERLINE); dotitle = dosize = 0; } else { printf ("%%!PS-Adobe-1.0\n"); if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); } if (banner) { printf ("%%%%Banner: %s\n", ps_chars (banner)); } if (credits) { printf ("%%%%Credits: %s\n", ps_chars (credits)); } if (creator) { printf ("%%%%Creator: %s\n", ps_chars (creator)); } printf ("%%%%CreationDate: %s", ctime (&clock)); printf ("%%%%Pages: 1\n"); printf ("%%%%DocumentFonts:%s%s\n", dotitle ? " Times-Bold" : "", dosize ? " Times-Roman" : ""); printf ("%%%%EndComments\n"); printf ("%%%%EndProlog\n"); printf ("%%%%Page: 1 1\n\n"); printf ("/inch { 72 mul } def\n"); printf ("/picstr %d string def\n\n", BYTESPERLINE); } printf ("gsave\n"); if (llx != 0.0 || lly != 0.0) { printf ("%lg inch %lg inch translate", llx, lly); } if (rotate) { fputs (" -90 rotate", stdout); } printf ("\n\n"); top = height + 0.125; bottom = -0.125; if (dotitle && title) { printf ("/Times-Bold findfont 14 scalefont setfont\n"); printf ("%lg inch %lg inch moveto\n", width/2.0, top); printf ("(%s)\n", ps_chars (title)); printf ("dup stringwidth pop 2 div 0 exch sub 0 rmoveto show\n\n"); top += (14.0 / 72.0) + 0.125; } if (credits && docredits) { bottom -= (8.0 / 72.0); printf ("/Times-Roman findfont 8 scalefont setfont\n"); printf ("%lg inch %lg inch moveto\n", width, bottom); printf ("(%s)\n", ps_chars (credits)); printf ("dup stringwidth pop 0 exch sub 0 rmoveto show\n\n"); } else if (dosize) { bottom -= (8.0 / 72.0); printf ("/Times-Roman findfont 8 scalefont setfont\n"); printf ("%lg inch %lg inch moveto\n", width, bottom); sprintf (buf, "[ %d by %d pixels, %1.3lf %s, %1.2lf by %1.2lf inches ]", image.hdr.cols, image.hdr.rows, image.hdr.aspect, "aspect ratio", width, height); printf ("(%s)\n", ps_chars (buf)); printf ("dup stringwidth pop 0 exch sub 0 rmoveto show\n\n"); } if (dobanner && banner) { printf ("/Times-Bold findfont 28 scalefont setfont\n"); printf ("%lg inch %lg inch moveto\n", width/2.0, top); printf ("(%s)\n", ps_chars (banner)); printf ("dup stringwidth pop 2 div 0 exch sub 0 rmoveto show\n\n"); top += (28.0 / 72.0) + 0.125; bottom -= (28.0 / 72.0); printf ("%lg inch %lg inch moveto\n", width/2.0, bottom); printf ("(%s)\n", ps_chars (banner)); printf ("dup stringwidth pop 2 div 0 exch sub 0 rmoveto show\n\n"); } printf ("%lg inch %lg inch scale\n", width, height); write_simple_ps (&image, stdout, iscolor, bits, padlen); printf ("grestore\n"); if (!scribe) { printf ("\nshowpage\n\n"); printf ("%%%%Trailer\n"); } exit (0); } /**************************************************************** * ps_chars: Put in proper escapes so an arbitrary string works * according to the PostScript definition of a literal ****************************************************************/ char *ps_chars (txt) char *txt; { static char buf[512]; register char *s = buf; char *index (); for (; *txt; txt++) { if (index ("()\\", *txt)) { *s++ = '\\'; *s++ = *txt; } else if (*txt < ' ' || *txt > '~') { sprintf (s, "\\%03o", *txt & 0377); s += 4; } else { *s++ = *txt; } } *s = '\0'; s = buf; return (s); }